home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / brailler-04b-c / brlr ƒ / Shell ƒ / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  10.2 KB  |  385 lines  |  [TEXT/MMCC]

  1. #include "program globals.h"
  2. #include "prefs.h"
  3. #include "help.h"
  4. #include "dialogs.h"
  5. #include "environment.h"
  6. #include "util.h"
  7. #include "window layer.h"
  8. #include "Folders.h"
  9.  
  10. #define        PREFS_FILE_NAME            "\pBrailler prefs"
  11. #define        PREFS_TYPE                'pref'
  12. // CREATOR is #defined in "program globals.h"
  13. #define        PREFS_HEADER_VERSION    1
  14.  
  15. Str255            gMyName;
  16. Str255            gMyOrg;
  17.  
  18. typedef struct
  19. {
  20.     long            fileID;
  21.     short            maintopic;
  22.     short            subtopic;
  23.     
  24.     char            regname[40];
  25.     char            regorg[40];
  26.     short            grade;
  27. } PrefStruct;
  28.  
  29. /* internal globals for use in prefs.c only */
  30. static long            gFileID;
  31. static Boolean        gCanSavePrefs;
  32. static PrefStruct    thePrefs;
  33. static long            gPrefsFilePos;
  34.  
  35. /*-----------------------------------------------------------------------------------*/
  36. /* internal stuff for prefs.c                                                        */
  37.  
  38. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  39. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  40. void ClosePrefsFile(short prefsFileID);
  41. enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  42. enum PrefErrorTypes SavePrefs(short prefsFileID);
  43. enum PrefErrorTypes CheckVersion(short prefsFileID);
  44. enum PrefErrorTypes GetFileID(void);
  45. enum PrefErrorTypes CheckFileID(void);
  46. enum PrefErrorTypes Virgin(short prefsFileID);
  47. void DefaultPrefs(void);
  48. void CopyGlobalsToPrefs(void);
  49. void CopyPrefsToGlobals(void);
  50. void GetRegistration(void);
  51.  
  52. void SaveThePrefs(void)
  53. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  54. {
  55.     short            prefsFileID;
  56.     
  57.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  58.     {
  59.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  60.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  61.         SavePrefs(prefsFileID);            /* save prefs to disk */
  62.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  63.     }
  64. }
  65.  
  66. enum PrefErrorTypes PreferencesInit(void)
  67. {
  68.     short            prefsFileID;
  69.     enum PrefErrorTypes        err;
  70.     
  71.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  72.     err=GetFileID();        /* get application file ID */
  73.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  74.         return err;
  75.     
  76.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  77.     if (err!=prefs_allsWell)
  78.     {
  79.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  80.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  81.         return err;
  82.     }
  83.     
  84.     err=CheckVersion(prefsFileID);        /* check prefs version */
  85.     if (err!=prefs_allsWell)
  86.     {
  87.         ClosePrefsFile(prefsFileID);
  88.         return err;
  89.     }
  90.     
  91.     GetFPos(prefsFileID, &gPrefsFilePos);
  92.     gPrefsFilePos-=sizeof(thePrefs);
  93.     do
  94.     {
  95.         gPrefsFilePos+=sizeof(thePrefs);
  96.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  97.         if (err==prefs_noMorePrefsErr)        /* or not */
  98.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  99.         
  100.         if (err!=prefs_allsWell)            /* any other error, just abort */
  101.         {
  102.             ClosePrefsFile(prefsFileID);
  103.             return err;
  104.         }
  105.         
  106.         err=CheckFileID();                    /* check file ID of current prefs struct */
  107.     }
  108.     while (err==prefs_IDNotMatchErr);
  109.     
  110.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  111.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  112.     
  113.     return prefs_allsWell;                    /* piece o' cake */
  114. }
  115.  
  116. void PrefsError(enum PrefErrorTypes err)
  117. {
  118.     Str255            tempStr;
  119.     
  120.     switch (err)
  121.     {
  122.         case prefs_diskReadErr:
  123.         case prefs_diskWriteErr:
  124.         case prefs_cantCreatePrefsErr:
  125.         case prefs_cantOpenPrefsErr:
  126.         case prefs_versionNotSupportedErr:
  127.             DefaultPrefs();                    /* use default prefs if error */
  128.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  129.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  130.             ParamText(tempStr, "\p", "\p", "\p");
  131.             PositionDialog('ALRT', largeAlert);
  132.             StopAlert(largeAlert, 0L);        /* display error alert */
  133.             break;
  134.         default:
  135.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  136.             break;
  137.     }
  138. }
  139.  
  140. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  141. {
  142.     short            thisFile;
  143.     Boolean            newPrefs;
  144.     unsigned char    *name=PREFS_FILE_NAME;
  145.     OSErr            isHuman;
  146.     short            vRefNum;
  147.     long            dirID;
  148.     FSSpec            prefsFile;
  149.     
  150.     newPrefs=FALSE;
  151.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  152.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  153.     
  154.     if (isHuman!=noErr)        /* screwed up already?!? */
  155.         return prefs_cantOpenPrefsErr;
  156.     
  157.     isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  158.     if (isHuman!=noErr)
  159.     {
  160.         if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  161.         {
  162.             isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  163.             if (isHuman!=noErr)                                        /* or not */
  164.                 return prefs_cantCreatePrefsErr;
  165.             newPrefs=TRUE;        /* signal that prefs file is new */
  166.         }
  167.         else return prefs_cantOpenPrefsErr;
  168.     }
  169.     isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  170.     *prefsFileID=thisFile;        /* store file reference number */
  171.     if (isHuman!=noErr)
  172.         return prefs_cantOpenPrefsErr;
  173.     
  174.     if (newPrefs)
  175.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  176.     
  177.     return prefs_allsWell;
  178. }
  179.  
  180. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  181. /* this writes the prefs version number to the newly created prefs file, so we can
  182.    tell if the prefs file was created by a later version of the program and is
  183.    therefore in a format that we don't support -- forward compatability!  what
  184.    a concept! */
  185. {
  186.     long            count;
  187.     short            temp;
  188.     
  189.     gPrefsFilePos=2L;
  190.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  191.         return prefs_diskWriteErr;
  192.     
  193.     SetFPos(prefsFileID, 1, 0L);
  194.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  195.     count=2L;
  196.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  197.         return prefs_diskWriteErr;        
  198.     
  199.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  200. }
  201.  
  202. void ClosePrefsFile(short prefsFileID)
  203. {
  204.     FSClose(prefsFileID);                /* close file on disk */
  205.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  206. }
  207.  
  208. enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  209. {
  210.     OSErr        isHuman;
  211.     long        count;
  212.     
  213.     count=sizeof(thePrefs);
  214.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  215.     if (isHuman==eofErr)    /* no more left */
  216.         return prefs_noMorePrefsErr;
  217.     if (isHuman!=noErr)        /* some other error */
  218.         return prefs_diskReadErr;
  219.     
  220.     return prefs_allsWell;
  221. }
  222.  
  223. enum PrefErrorTypes SavePrefs(short prefsFileID)
  224. {
  225.     long        oldEOF;
  226.     long        count;
  227.     
  228.     GetEOF(prefsFileID, &oldEOF);
  229.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  230.     {
  231.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  232.             return prefs_diskWriteErr;
  233.     }
  234.     
  235.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  236.     count=sizeof(thePrefs);
  237.     /* write prefs struct and return appropriate error code */
  238.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  239.         prefs_diskWriteErr : prefs_allsWell;
  240. }
  241.  
  242. enum PrefErrorTypes CheckVersion(short prefsFileID)
  243. {
  244.     OSErr        isHuman;
  245.     long        count;
  246.     short            temp;
  247.     
  248.     count=2L;
  249.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  250.     if (isHuman!=noErr)
  251.         return prefs_diskReadErr;
  252.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  253.         return prefs_versionNotSupportedErr;
  254.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  255.         return SetupNewPrefsFile(prefsFileID);
  256.     
  257.     return prefs_allsWell;
  258. }
  259.  
  260. enum PrefErrorTypes GetFileID(void)
  261. {
  262.     ParamBlockRec    pb;
  263.     
  264.     pb.fileParam.ioCompletion=0L;
  265.     pb.fileParam.ioNamePtr=LMGetCurApName();
  266.     pb.fileParam.ioVRefNum=0;
  267.     pb.fileParam.ioFVersNum=0;
  268.     pb.fileParam.ioFDirIndex=0;
  269.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  270.         return prefs_diskReadErr;
  271.     
  272.     gFileID=pb.fileParam.ioFlNum;
  273.     
  274.     return prefs_allsWell;
  275. }
  276.  
  277. enum PrefErrorTypes CheckFileID(void)
  278. {
  279.     /* compare file ID in current prefs struct to application's file ID */
  280.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  281. }
  282.  
  283. enum PrefErrorTypes Virgin(short prefsFileID)
  284. {
  285.     enum PrefErrorTypes    err;
  286.     
  287.     DefaultPrefs();
  288.     CopyGlobalsToPrefs();
  289.     err=SavePrefs(prefsFileID);
  290.     if (err!=prefs_allsWell)
  291.         return err;
  292.     GetRegistration();
  293.     CopyGlobalsToPrefs();
  294.     err=SavePrefs(prefsFileID);
  295.     
  296.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  297. }
  298.  
  299. void DefaultPrefs(void)
  300. {
  301.     unsigned char        *bob="\pBob";
  302.     
  303.     gMainTopicShowing=gSubTopicShowing=0;
  304.     
  305.     Mymemcpy((Ptr)gMyName, (Ptr)bob, bob[0]+1);
  306.     gMyOrg[0]=0x00;
  307.     
  308.     gGrade=1;
  309. }
  310.  
  311. void CopyGlobalsToPrefs(void)
  312. {
  313.     Mymemset((Ptr)(&thePrefs), 0, sizeof(thePrefs));
  314.     if (gMyName[0]>0x27)
  315.         gMyName[0]=0x27;
  316.     if (gMyOrg[0]>0x27)
  317.         gMyOrg[0]=0x27;
  318.     Mymemcpy((Ptr)thePrefs.regname, (Ptr)gMyName, gMyName[0]+1);
  319.     Mymemcpy((Ptr)thePrefs.regorg, (Ptr)gMyOrg, gMyOrg[0]+1);
  320.     thePrefs.maintopic=gMainTopicShowing;
  321.     thePrefs.subtopic=gSubTopicShowing;
  322.     thePrefs.fileID=gFileID;
  323.     
  324.     thePrefs.grade=gGrade;
  325. }
  326.  
  327. void CopyPrefsToGlobals(void)
  328. {
  329.     Mymemcpy((Ptr)gMyName, (Ptr)thePrefs.regname, thePrefs.regname[0]+1);
  330.     Mymemcpy((Ptr)gMyOrg, (Ptr)thePrefs.regorg, thePrefs.regorg[0]+1);
  331.     gMainTopicShowing=thePrefs.maintopic;
  332.     gSubTopicShowing=thePrefs.subtopic;
  333.     
  334.     gGrade=thePrefs.grade;
  335. }
  336.  
  337. void GetRegistration(void)
  338. {
  339.     DialogPtr        theDlog;
  340.     short            itemSelected = 0;
  341.     short            newleft;
  342.     short            newtop;
  343.     short            itemType;
  344.     Handle            item;
  345.     Rect            box;
  346.     
  347.     RemoveHilitePatch();
  348.     
  349.     theDlog = GetNewDialog(131, 0L, (WindowPtr)-1L);
  350.     newleft = qd.screenBits.bounds.left + (((qd.screenBits.bounds.right -
  351.                 qd.screenBits.bounds.left) - (theDlog->portRect.right -
  352.                 theDlog->portRect.left)) / 2);
  353.     newtop = qd.screenBits.bounds.top + (((qd.screenBits.bounds.bottom -
  354.                 qd.screenBits.bounds.top) - (theDlog->portRect.bottom -
  355.                 theDlog->portRect.top)) / 2);
  356.     if(newtop < 15)
  357.         newtop = 15;
  358.     GetDItem(theDlog, 1, &itemType, &item, &box);
  359.     InsetRect(&box, -4, -4);
  360.     SetDItem(theDlog, 8, userItem, (Handle)OutlineDefaultButton, &box);
  361.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  362.     
  363.     MoveWindow(theDlog, newleft, newtop, TRUE);
  364.     ShowWindow(theDlog);
  365.     while(itemSelected != 1)
  366.     {
  367.         ModalDialog(0L, &itemSelected);
  368.     }
  369.     GetDItem(theDlog,4,&itemType,&item,&box);
  370.     GetIText(item,gMyName);
  371.     
  372.     GetDItem(theDlog,5,&itemType,&item,&box);
  373.     GetIText(item,gMyOrg);
  374.  
  375.     if (gMyName[0]==0x00)
  376.         DefaultPrefs();
  377.  
  378.     HideWindow(theDlog);
  379.     DisposeDialog(theDlog);
  380.     
  381.     gIsVirgin=TRUE;
  382.     
  383.     InstallHilitePatch();
  384. }
  385.